﻿using System;
using System.Collections.Generic;
using System.Linq;
using LayeredArchitectureSample.DataTransferObjects;
using LayeredArchitectureSample.Infrastructure;
using LayeredArchitectureSample.Infrastructure.Services;
using LayeredArchitectureSample.ServiceContracts;

namespace LayeredArchitectureSample.RandomDataProviders
{
    class RandomLocationProvider : IRandomLocationProvider
    {
        private readonly IServiceOperationInvoker<IRemoteLocationRepository> _locationRepository;

        public RandomLocationProvider(IServiceOperationInvoker<IRemoteLocationRepository> locationRepository)
        {
            if (locationRepository == null) throw new ArgumentNullException("locationRepository");
            _locationRepository = locationRepository;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="numberOfLocations"></param>
        /// <returns></returns>
        /// <exception cref="CannotProvideRandomObjectException"></exception>
        public IEnumerable<LocationDto> GetRandomLocations(int numberOfLocations)
        {
            List<LocationDto> allLocations = _locationRepository.Invoke(r=>r.GetAll().ToList());

            if (allLocations.Count < numberOfLocations)
            {
                throw new CannotProvideRandomObjectException("Need at least the following number of locations in the repository: {0}. Please add them and try again.".FormatWith(numberOfLocations));
            }
            
            var random = new Random();
            var locations = new HashSet<LocationDto>(); // Yeah, no worries about the shuffling
            
            while (locations.Count < numberOfLocations)
            {
                locations.Add(allLocations[random.Next(allLocations.Count)]);
            }

            return locations;
        }
    }
}